From 33c5f3c193e5592ff4ee09be33b72d2fb48732b7 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Thu, 4 May 2017 13:49:34 +0200 Subject: [PATCH] gtkmain: Add API to get the target of a GdkEvent This can be used on grabbing situations to determine the target of the event. This mainly matters for GtkMenu. --- gtk/gtkmain.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ gtk/gtkmain.h | 7 +++++++ 2 files changed, 54 insertions(+) diff --git a/gtk/gtkmain.c b/gtk/gtkmain.c index 910ff0e9fb..33429accf7 100644 --- a/gtk/gtkmain.c +++ b/gtk/gtkmain.c @@ -1329,6 +1329,7 @@ synth_crossing_for_motion (GtkWidget *widget, gdouble x, y; event = gdk_event_new (enter ? GDK_ENTER_NOTIFY : GDK_LEAVE_NOTIFY); + gdk_event_set_user_data (event, G_OBJECT (widget)); gdk_event_set_device (event, gdk_event_get_device (source)); gdk_event_set_source_device (event, gdk_event_get_source_device (source)); @@ -1678,6 +1679,8 @@ gtk_main_do_event (GdkEvent *event) if (check_event_in_child_popover (event_widget, grab_widget)) grab_widget = event_widget; + gdk_event_set_user_data (event, G_OBJECT (event_widget)); + /* If the widget receiving events is actually blocked by another * device GTK+ grab */ @@ -2361,6 +2364,50 @@ gtk_get_event_widget (GdkEvent *event) return widget; } +/** + * gtk_get_event_target: + * @event: a #GdkEvent + * + * If @event is %NULL or the event was not associated with any widget, + * returns %NULL, otherwise returns the widget that is the deepmost + * receiver of the event. + * + * Returns: (transfer none) (nullable): the target widget, or %NULL + * + * Since: 3.90 + */ +GtkWidget * +gtk_get_event_target (GdkEvent *event) +{ + return GTK_WIDGET (gdk_event_get_user_data (event)); +} + +/** + * gtk_get_event_target_with_type: + * @event: a #GdkEvent + * + * If @event is %NULL or the event was not associated with any widget, + * returns %NULL, otherwise returns first widget found from the event + * target to the toplevel that matches @type. + * + * Returns: (transfer none) (nullable): the widget in the target stack + * with the given type, or %NULL + * + * Since: 3.90 + */ +GtkWidget * +gtk_get_event_target_with_type (GdkEvent *event, + GType type) +{ + GtkWidget *target; + + target = gtk_get_event_target (event); + while (target && !g_type_is_a (G_OBJECT_TYPE (target), type)) + target = gtk_widget_get_parent (target); + + return target; +} + static gboolean propagate_event_up (GtkWidget *widget, GdkEvent *event, diff --git a/gtk/gtkmain.h b/gtk/gtkmain.h index 49e19c9f22..47681bee1a 100644 --- a/gtk/gtkmain.h +++ b/gtk/gtkmain.h @@ -151,6 +151,13 @@ GdkDevice *gtk_get_current_event_device (void); GDK_AVAILABLE_IN_ALL GtkWidget *gtk_get_event_widget (GdkEvent *event); +GDK_AVAILABLE_IN_3_90 +GtkWidget *gtk_get_event_target (GdkEvent *event); + +GDK_AVAILABLE_IN_3_90 +GtkWidget *gtk_get_event_target_with_type (GdkEvent *event, + GType type); + GDK_AVAILABLE_IN_ALL void gtk_propagate_event (GtkWidget *widget, GdkEvent *event); -- 2.30.2